package com.strive.village.controller;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.map.MapUtil;
import com.google.code.kaptcha.Producer;
import com.strive.village.common.Const;
import com.strive.village.common.Result;
import com.strive.village.entity.SysUser;
import com.strive.village.entity.dto.SysMenuDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@RestController
public class AuthController extends BaseController {

    @Autowired // 自动注入相关依赖并管理这个对象
    private Producer producer;

    @Value("${ip.api.url}")
    private String IP_API_URL;

    /**
     * 生成图片验证码
     */
    @GetMapping("/captcha")
    public Result captcha() throws IOException {
        String uuid = UUID.randomUUID().toString();
        String code = producer.createText(); // 生成一个随机的5位数的验证码

        BufferedImage image = producer.createImage(code);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream); // 把图片写入流，格式为JPG

        Base64Encoder encoder = new Base64Encoder();
        String str = "data:image/jpeg;base64,"; // 固定前缀

        String base64Imag = str + Base64Encoder.encode(outputStream.toByteArray()); // 前缀+图片的字节码
        redisUtils.hset(Const.CAPTCHA_KEY, uuid, code, 120); // 存入哈希中
        return Result.success(
                MapUtil.builder().put("uuid", uuid) // 名字与前端保持一致
                        .put("captchaImg", base64Imag)
                        .build()
        );
    }

    /**
     * 获取当前用户信息以及导航栏信息和权限信息
     */
    @GetMapping("/userInfo")
    public Result getUserInfo(Principal principal) {
        // 用户信息
        SysUser user = sysUserService.getByUsername(principal.getName());

        // 动态导航菜单信息
        List<SysMenuDto> navs = sysMenuService.getCurrentUserNav();

        // 权限信息
        String authorityInfo = sysUserService.getUserAuthorityInfo(user.getId());
        String[] authorityInfoArray = StringUtils.tokenizeToStringArray(authorityInfo, ",");

        return Result.success(
                MapUtil.builder()
                        .put("navs", navs)
                        .put("userInfo", user)
                        .put("authorityInfoArray", authorityInfoArray)
                        .build()
        );
    }

    /**
     * 获取用户登录的时间地址
     *
     * @return 返回登录信息
     */
    @GetMapping("/loginInfo")
    public Result getLoginInfo() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            System.out.println(authentication.getDetails());
            if (authentication == null || !(authentication.getDetails() instanceof WebAuthenticationDetails)) {
                return Result.fail("无法获取登录信息");
            }

            WebAuthenticationDetails details = (WebAuthenticationDetails) authentication.getDetails();
            String ipAddress = details.getRemoteAddress();

            if (ipAddress == null) {
                return Result.fail("无法获取客户端IP地址");
            }

            RestTemplate restTemplate = new RestTemplate();
            String url = IP_API_URL + ipAddress;
            Map<String, Object> location = restTemplate.getForObject(url, Map.class);
            LocalDateTime loginTime = LocalDateTime.now();

            return Result.success(MapUtil.builder()
                    .put("loginTime", loginTime)
                    .put("location", location)
                    .put("ipAddress", ipAddress)
                    .build());
        } catch (Exception e) {
            // 处理异常情况
            e.printStackTrace();
            return Result.fail("获取登录信息失败");
        }
    }
}
